﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Threading;

namespace WebStoreClient
{
    public partial class WebStoreClient
    {
        public HttpClient Client { get; private set; }
        private Thread thUpdateToken { get; set; }
        public TimeSpan TokenInterval { get; private set; }
        public string TokenUrl { get; private set; }
        public Action<string> LogWriter { get; set; }
        public string StoreProduUrl { get; private set; }
        public WebStoreClient(Uri uri,TimeSpan updateTokenInterval, string tokenUrl,string storeProduUrl)
        {
            Client = new HttpClient();
            Client.BaseAddress = uri;
            Client.Timeout = TimeSpan.FromMinutes(2); 
            Client.DefaultRequestHeaders.UserAgent.Add(new System.Net.Http.Headers.ProductInfoHeaderValue("WebStoreClient", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()));
            Client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
            Client.DefaultRequestHeaders.AcceptCharset.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("utf-8"));


            TokenUrl = tokenUrl;
            StoreProduUrl = storeProduUrl;
            TokenInterval = updateTokenInterval;

            thUpdateToken = new Thread(new ThreadStart(UpdateTokenJob));
            thUpdateToken.IsBackground = true;
            thUpdateToken.Start();
        }
        private bool ResetToken(HttpResponseMessage result,ref ErrorMsg error)
        {
            if(result != null && result.Content!=null && result.IsSuccessStatusCode)
            { 
                MsgResult msg = Newtonsoft.Json.JsonConvert.DeserializeObject<MsgResult>(result.Content.ReadAsStringAsync().Result);
                if (msg.state == E_States.Y)
                {
                    Client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", msg.msg);
                    return true;
                }
                else
                {
                    error = new ErrorMsg()
                    {
                        Message = msg.msg
                    };
                    return false;
                }

            }
            else
            {
                return false;
            }
        }
        private void Log(string msg)
        {
            try
            {
                if (LogWriter != null)
                {
                    LogWriter(msg+Environment.NewLine);
                }
            }catch(Exception ex)
            {

            }
        }
        private void UpdateTokenJob()
        {
            while (true)
            {
                try
                {
                    if (Client != null)
                    {
                        var result = Client.GetAsync(TokenUrl).Result;
                        if(result.IsSuccessStatusCode)
                        {
                            ErrorMsg error = new ErrorMsg();
                            if (ResetToken(result,ref error))
                            {
                                Log("更新token成功");

                            }
                            else
                            {
                                Log("更新token失败:" + error.Message + "," + error.ExceptionMessage);

                            }
                        }
                        else
                        {
                            ErrorMsg error = new ErrorMsg(result);
                            Log("更新token失败:" + error.Message + "," + error.ExceptionMessage);
                        }
                    }

                    Thread.Sleep(TokenInterval);
                }
                catch (ThreadAbortException tae)
                {

                }
                catch (Exception ex)
                {
                    Log("更新Token线程因为异常失败,"+ex.Message);
                }
            }
        }

        public bool Login(string username,string password,ref ErrorMsg error)
        {
            var result=Client.PostAsync(
                TokenUrl, 
                new StringContent(
                    Newtonsoft.Json.JsonConvert.SerializeObject(
                        new M_USERPASSWORD()
                        {
                            USERCODE=username,
                            PASSWORD=password
                        }
                    ),
                    Encoding.UTF8,
                   "application/json"
                )
            
            ).Result;

            if (result.IsSuccessStatusCode)
            {
                if (ResetToken(result,ref error))
                {
                    return true;
                }
                else
                {
                    return false;
                }

            }
            else
            {
                error = new ErrorMsg(result);

                return false;
            }
        }
        public List<StoreProduResult> StoreProduExecute(List<StoreProdu> sps)
        {
            var json = Newtonsoft.Json.JsonConvert.SerializeObject(sps);
            if (json == null)
            {
                throw new ArgumentNullException("sp不可为null");
            }

            var result = Client.PostAsync(StoreProduUrl+ "?batch=", new StringContent(
                json,
                    Encoding.UTF8,
                   "application/json")).Result;
            if (result.IsSuccessStatusCode)
            {
                return Newtonsoft.Json.JsonConvert.DeserializeObject<List<StoreProduResult>>(result.Content.ReadAsStringAsync().Result);
            }
            else
            {
                ErrorMsg msg = new ErrorMsg(result);
                if (result.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                {
                    throw new WsNeedLoginException(msg.Message + Environment.NewLine + msg.ExceptionMessage);
                }
                else if (result.StatusCode == System.Net.HttpStatusCode.Forbidden)
                {
                    throw new WsForbiddenException(msg.Message + Environment.NewLine + msg.ExceptionMessage);
                }
                else
                {
                    throw new Exception(msg.Message + ";" + msg.ExceptionMessage);
                }
            }

        }
        public StoreProduResult StoreProduExecute(StoreProdu sp)
        {
            var json = Newtonsoft.Json.JsonConvert.SerializeObject(sp);
            if (json == null)
            {
                throw new ArgumentNullException("sp不可为null");
            }

            var result = Client.PostAsync(StoreProduUrl, new StringContent(json,
                    Encoding.UTF8,
                   "application/json")).Result;
            if (result.IsSuccessStatusCode)
            {
                return Newtonsoft.Json.JsonConvert.DeserializeObject<StoreProduResult>(result.Content.ReadAsStringAsync().Result);
            }
            else
            {
                ErrorMsg msg = new ErrorMsg(result);
                if (result.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                {
                    throw new WsNeedLoginException(msg.Message + Environment.NewLine + msg.ExceptionMessage);
                }else if (result.StatusCode == System.Net.HttpStatusCode.Forbidden)
                {
                    throw new WsForbiddenException(msg.Message + Environment.NewLine + msg.ExceptionMessage);
                }
                else
                {
                    throw new Exception(msg.Message + ";" + msg.ExceptionMessage);
                }
            }
        }
        /// <summary>
        /// 登陆信息
        /// </summary>
        private class M_USERPASSWORD
        {
            /// <summary>
            /// 用户名
            /// </summary>
            public string USERCODE { get; set; }
            /// <summary>
            /// 密码
            /// </summary>
            public string PASSWORD { get; set; }
        }
        ~WebStoreClient()
        {
            try
            {
                if (thUpdateToken != null)
                {
                    thUpdateToken.Abort();
                    thUpdateToken.Join(2000);
                }
            }
            catch { }
        }
    }
}
